﻿using WPay.Domain.Model.DTOs;
using WPay.Infrastructure.Unity;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace WPay.Web.API
{
    /// <summary>
    /// 异常日志捕获中间件
    /// </summary>
    public class ExceptionMiddleware
    {
        private readonly RequestDelegate next;
        //private readonly ILogger logger;
        private IHostingEnvironment environment;
        /// <summary>
        /// 当前请求地址
        /// </summary>
        private string path;

        //public ExceptionMiddleware(RequestDelegate next, ILogger<ExceptionMiddleware> logger, IHostingEnvironment environment)
        public ExceptionMiddleware(RequestDelegate next, IHostingEnvironment environment)
        {
            this.next = next;
            //this.logger = logger;
            this.environment = environment;
        }

        public async Task Invoke(HttpContext context)
        {
            try
            {
                //当前请求地址
                path = context.Request.Host + context.Request.Path;

                //Hashtable data = new Hashtable();
                //data.Add("ErrorPath", path);
                context.Response.ContentType = "text/json;charset=utf-8;";
                await next.Invoke(context);
                //捕获404异常
                if (context.Response.StatusCode == 404)
                {
                    context.Response.StatusCode = 200;
                    await context.Response.WriteAsync(JSONSerializer.Serialize(new RespDto(false, 404, "您的请求地址错误！")));
                }
                var features = context.Features;
            }
            catch (Exception e)
            {
                await HandleException(context, e);
            }
        }
        /// <summary>
        /// 捕获控制器异常
        /// </summary>
        /// <param name="context"></param>
        /// <param name="e"></param>
        /// <returns></returns>
        private async Task HandleException(HttpContext context, Exception e)
        {
            context.Response.StatusCode = 500;
            context.Response.ContentType = "text/json;charset=utf-8;";
            //当前请求地址
            path = context.Request.Host + context.Request.Path;
            string param = "";
            if (context.Request.Query != null)
                param = JSONSerializer.Serialize(context.Request.Query);
            if (context.Request.HasFormContentType)
                param += JSONSerializer.Serialize(context.Request.Form);
            string error;
            //void ReadException(Exception ex)
            //{
            //    error += string.Format("{0} | {1} | {2}", ex.Message, ex.StackTrace, ex.InnerException);
            //    if (ex.InnerException != null)
            //    {
            //        ReadException(ex.InnerException);
            //    }
            //}

            // ReadException(e);
            if (environment.IsDevelopment() && e.GetType() == typeof(UNException))
            {
                //var json = new { message = e.Message, detail = error };
                error = JSONSerializer.Serialize(new RespDto(false, 200, e.Message));
            }
            else
                error = JSONSerializer.Serialize(new RespDto(false, 500, "抱歉，系统发生故障！"));
            ErrorLog(context, 200, e.Message);
            await context.Response.WriteAsync(error);
        }

        private void ErrorLog(HttpContext _context,int _errorCode,string _errorMessage) {

            var requestURL = _context.Request.Host.Host + "|" + _context.Request.Path.Value + "|" + (string.Join("&", _context.Request.Form.Keys.Select(c => c + "=" + _context.Request.Form[c])));

            var log = new
            {
                ActionAddress = requestURL,
                FuncName = _context.Request.Path.Value,
                HostName = _context.Request.Host.Host,
                Msg = _errorMessage,
                Type = _errorCode
            };
            //DynamoDBBase dynamo = new DynamoDBBase(typeof(log));
            //dynamo.Insert_ByTable(log);
        }
    }
}
